from typing import List, Dict, Any, Optional
from pydantic import BaseModel, Field
from datetime import datetime
from enum import Enum
import uuid


class ActionType(str, Enum):
    """动作类型枚举"""
    NAVIGATE = "navigate"
    CLICK = "click"
    INPUT = "input"
    KEYBOARD = "keyboard"
    WAIT = "wait"
    SCROLL = "scroll"
    HOVER = "hover"


class BrowserType(str, Enum):
    """浏览器类型枚举"""
    CHROMIUM = "chromium"
    FIREFOX = "firefox"
    WEBKIT = "webkit"


class ScriptStatus(str, Enum):
    """脚本状态枚举"""
    DRAFT = "draft"          # 草稿
    ACTIVE = "active"        # 激活
    DISABLED = "disabled"    # 禁用
    ARCHIVED = "archived"    # 归档


class ActionModel(BaseModel):
    """动作数据模型"""
    type: ActionType
    timestamp: datetime
    data: Dict[str, Any] = Field(default_factory=dict)
    description: Optional[str] = None
    
    class Config:
        use_enum_values = True


class AssertionModel(BaseModel):
    """断言数据模型"""
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    type: str  # text_equals, text_contains, element_visible, etc.
    selector: str = ""
    expected_value: str = ""
    description: Optional[str] = None
    line_number: int = -1
    created_at: datetime = Field(default_factory=datetime.now)
    
    class Config:
        use_enum_values = True


class ScriptModel(BaseModel):
    """脚本数据模型"""
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    name: str
    description: Optional[str] = None
    created_at: datetime = Field(default_factory=datetime.now)
    updated_at: datetime = Field(default_factory=datetime.now)
    browser_type: BrowserType = BrowserType.CHROMIUM
    status: ScriptStatus = ScriptStatus.DRAFT
    
    # 脚本内容
    actions: List[ActionModel] = Field(default_factory=list)
    assertions: List[AssertionModel] = Field(default_factory=list)
    generated_code: Optional[str] = None
    
    # 执行统计
    execution_count: int = 0
    last_execution: Optional[datetime] = None
    success_rate: float = 0.0
    
    # 标签和分类
    tags: List[str] = Field(default_factory=list)
    category: Optional[str] = None
    
    # 文件路径
    file_path: Optional[str] = None
    
    class Config:
        use_enum_values = True
    
    def add_action(self, action: ActionModel) -> None:
        """添加动作"""
        self.actions.append(action)
        self.updated_at = datetime.now()
    
    def add_assertion(self, assertion: AssertionModel) -> None:
        """添加断言"""
        self.assertions.append(assertion)
        self.updated_at = datetime.now()
    
    def remove_assertion(self, assertion_id: str) -> bool:
        """删除断言"""
        for i, assertion in enumerate(self.assertions):
            if assertion.id == assertion_id:
                del self.assertions[i]
                self.updated_at = datetime.now()
                return True
        return False
    
    def update_execution_stats(self, success: bool) -> None:
        """更新执行统计"""
        self.execution_count += 1
        self.last_execution = datetime.now()
        
        # 计算成功率 (简单移动平均)
        if self.execution_count == 1:
            self.success_rate = 1.0 if success else 0.0
        else:
            # 使用加权平均，新结果权重更高
            weight = 0.3
            current_success = 1.0 if success else 0.0
            self.success_rate = (1 - weight) * self.success_rate + weight * current_success
        
        self.updated_at = datetime.now()


class ExecutionResult(BaseModel):
    """执行结果模型"""
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    script_id: str
    script_name: str
    started_at: datetime = Field(default_factory=datetime.now)
    completed_at: Optional[datetime] = None
    duration: float = 0.0
    success: bool = False
    output: str = ""
    error: str = ""
    browser_type: BrowserType = BrowserType.CHROMIUM
    
    class Config:
        use_enum_values = True
    
    @property
    def status(self) -> str:
        """获取执行状态"""
        if self.completed_at is None:
            return "running"
        return "success" if self.success else "failed"


class ScriptFilter(BaseModel):
    """脚本过滤条件"""
    name: Optional[str] = None
    status: Optional[ScriptStatus] = None
    browser_type: Optional[BrowserType] = None
    category: Optional[str] = None
    tags: List[str] = Field(default_factory=list)
    created_after: Optional[datetime] = None
    created_before: Optional[datetime] = None
    
    class Config:
        use_enum_values = True